/**
 * 全局错误处理工具
 */

import { logger } from './logger';

export interface AppError extends Error {
  code?: string;
  statusCode?: number;
  isOperational?: boolean;
}

export class CustomError extends Error implements AppError {
  public readonly code: string;
  public readonly statusCode: number;
  public readonly isOperational: boolean;

  constructor(
    message: string,
    code: string = 'UNKNOWN_ERROR',
    statusCode: number = 500,
    isOperational: boolean = true,
  ) {
    super(message);
    this.name = this.constructor.name;
    this.code = code;
    this.statusCode = statusCode;
    this.isOperational = isOperational;

    Error.captureStackTrace(this, this.constructor);
  }
}

export class ValidationError extends CustomError {
  constructor(message: string) {
    super(message, 'VALIDATION_ERROR', 400);
  }
}

export class NetworkError extends CustomError {
  constructor(message: string) {
    super(message, 'NETWORK_ERROR', 503);
  }
}

export class FileError extends CustomError {
  constructor(message: string) {
    super(message, 'FILE_ERROR', 500);
  }
}

export class PluginError extends CustomError {
  constructor(message: string) {
    super(message, 'PLUGIN_ERROR', 500);
  }
}

/**
 * 全局错误处理器
 */
export class ErrorHandler {
  public static handleError(error: Error | AppError): void {
    logger.error('Application Error:', error);

    if (this.isTrustedError(error)) {
      this.handleTrustedError(error as AppError);
    } else {
      this.handleCriticalError(error);
    }
  }

  private static isTrustedError(error: Error): boolean {
    if (error instanceof CustomError) {
      return error.isOperational;
    }
    return false;
  }

  private static handleTrustedError(error: AppError): void {
    // 处理可预期的错误
    logger.warn(`Trusted Error [${error.code}]: ${error.message}`);
    
    // 可以在这里添加用户通知逻辑
    this.notifyUser(error);
  }

  private static handleCriticalError(error: Error): void {
    // 处理严重错误
    logger.error('Critical Error:', error);
    
    // 上报错误
    logger.reportError(error);
    
    // 在开发环境下，可以选择退出进程
    if (process.env.NODE_ENV === 'development') {
      console.error('Critical error occurred. Check logs for details.');
    }
  }

  private static notifyUser(error: AppError): void {
    // 这里可以集成 UI 通知组件
    // 例如：ElMessage.error(error.message)
    console.warn('User notification:', error.message);
  }
}

/**
 * Promise 错误处理装饰器
 */
export function handleAsyncError<T extends (...args: any[]) => Promise<any>>(
  target: any,
  propertyName: string,
  descriptor: TypedPropertyDescriptor<T>,
): TypedPropertyDescriptor<T> {
  const method = descriptor.value!;

  descriptor.value = (async function (this: any, ...args: any[]) {
    try {
      return await method.apply(this, args);
    } catch (error) {
      ErrorHandler.handleError(error as Error);
      throw error;
    }
  }) as T;

  return descriptor;
}

/**
 * 安全执行异步函数
 */
export async function safeAsync<T>(
  fn: () => Promise<T>,
  fallback?: T,
): Promise<T | undefined> {
  try {
    return await fn();
  } catch (error) {
    ErrorHandler.handleError(error as Error);
    return fallback;
  }
}